"""
author:dlr123
date:2021年11月16日
"""
import numpy as np
import pandas as pd
from itertools import permutations


def generate_multi_index(value_num,everytree_num,conn_layer_num=1) :
    """:ivar

    :parameter
    value_num:变量的数量
    everytree_num:每棵树表征的变量数量
    conn_layer_num:用于保留连接关系的层数
    """
    # everytree_extra_num = everytree_num + conn_layer_num
    tree_num = int(np.ceil(value_num/everytree_num))
    multi_tree_indies = np.zeros((tree_num,value_num),dtype=np.uint8)
    current_tree = np.arange(value_num).astype(np.uint8)
    last_tree = None
    for i in range(tree_num) :
        multi_tree_indies[i] = current_tree
        last_tree = current_tree
        current_tree = np.hstack([last_tree[everytree_num :],last_tree[:everytree_num]])
    return tree_num,multi_tree_indies


def extra_layers(mcts_list,extra_num,eve_mcts_thre=None) :
    """
    :param mcts_list 训练出来的树集合 ->list
    :param extra_num  每棵树需要提取的变量数 ->int
    :param eve_mcts_thre 每棵树提取时的过滤阈值 ->list
    :return 返回生成的新的list
    """
    new_values_list = []
    tree_num = len(mcts_list)
    if eve_mcts_thre is not None :
        if len(eve_mcts_thre) != tree_num :
            raise ValueError("tree num is not suitable")
    else :
        eve_mcts_thre = np.full(tree_num,0.5)
    for i,mcts in enumerate(mcts_list) :
        new_values_list.extend(mcts.merge_layer(thre=eve_mcts_thre[i])[:extra_num])
    return new_values_list


# def evaluate_one_layer(mcts,goal_value,extra_num=1):
#     """
#     目前只实现了提取一层的功能
#     :param mcts:
#     :param goal_value:
#     :param extra_num:
#     :param thre:
#     :return:
#     """
#
#     # new_value_list = mcts.merge_layer(thre)[:extra_num]
#     cur_node = mcts.root
#     child_num = len(cur_node.children)
#     cur_num = 0
#     while(cur_node.depth != extra_num - 1):
#         cur_child = pd.Series(cur_node.children)[new_value_list[cur_num]]
#         cur_score = goal_value - cur_child.apply(lambda x:x.min_score).mean()
#
#         pass
#     pass
#
# def evaluate_result(new_values_list,mcts_list,goal_values_list) :
#
#     """
#     :param new_values_list:
#     :param mcts_list:
#     :param goal_values_list:
#     :return:
#     """
#
#     pass
